package model;

import java.util.ArrayList;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import mapproviderapi.Coordinate;
import mapproviderapi.GoogleStaticMapProvider;
import mapproviderapi.MapProvider;
import mapproviderapi.MapTile;
import mapproviderapi.OpenStreetMapProvider;

public class SimpleMap implements Map {
	private MapProvider mapProvider;

	//ThreadPool parameter
	protected int poolSize = 5;
	protected int maxPoolSize = 10;
	protected long keepLiveTime = 60;
	protected TimeUnit timeUnit = TimeUnit.SECONDS;
	protected int sizeQueue = 20;
	protected ArrayBlockingQueue<Runnable> arrayThreadQueue;
	ThreadPoolExecutor threadPool;
	
	public SimpleMap(MapProvider mapProvider){
		this.mapProvider = mapProvider;
		arrayThreadQueue = new ArrayBlockingQueue<Runnable>(sizeQueue);
		threadPool = new ThreadPoolExecutor(poolSize, maxPoolSize, keepLiveTime, timeUnit, arrayThreadQueue);
	}
	
	@Override
	public List<MapTileImage> getMapTileImages(double latitudeCenter,
			double longitudeCenter, int zoom) {
		
		try {
            Iterator<Runnable> it = threadPool.getQueue().iterator();
            while (it.hasNext()) {
                Runnable r = it.next();
                if (r instanceof Future<?>) {
                    Future<?> c = (Future<?>)r;
                    c.cancel(true);
                }
            }
        } catch (ConcurrentModificationException e) {            
        }
        threadPool.purge();
		
		List<MapTileImage> listMapTileImage = new ArrayList<MapTileImage>();
		List<MapTile> listMapTile = mapProvider.getMapTiles(new Coordinate(latitudeCenter, longitudeCenter), zoom);
		for (MapTile mapTile : listMapTile){
			MapTileImage mapTileImage = new MapTileImage(mapTile);
			listMapTileImage.add(mapTileImage);
			threadPool.execute(mapTileImage);
		}
		
		return listMapTileImage;
	}
	
	
}
